package com.ruyuan.commodity.common.mamager.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruyuan.commodity.enums.GoodsHaveSpecEnums;
import com.ruyuan.commodity.model.goods.dos.GoodsDO;
import com.ruyuan.commodity.model.goods.dos.GoodsGalleryDO;
import com.ruyuan.commodity.model.goods.dos.GoodsSkuDO;
import com.ruyuan.commodity.model.goods.dto.GoodsQueryParam;
import com.ruyuan.commodity.model.goods.vo.GoodsQuantityVO;
import com.ruyuan.commodity.model.goods.vo.GoodsSelectorSkuVO;
import com.ruyuan.commodity.model.goods.vo.GoodsSkuVO;
import com.ruyuan.commodity.model.goods.vo.SpecValueVO;
import com.ruyuan.commodity.mq.MqMessageSenderFactory;
import com.ruyuan.commodity.enums.MsgTypeEnums;
import com.ruyuan.commodity.open.api.model.common.WebPage;
import com.ruyuan.commodity.common.mamager.*;
import com.ruyuan.commodity.common.mapper.CategoryMapper;
import com.ruyuan.commodity.common.mapper.GoodsMapper;
import com.ruyuan.commodity.common.mapper.GoodsSkuMapper;
import com.ruyuan.commodity.exception.ServiceException;
import com.ruyuan.commodity.open.api.model.goods.enums.GoodsType;
import com.ruyuan.commodity.open.api.model.goods.enums.QuantityType;
import com.ruyuan.commodity.utils.*;
import com.ruyuan.commodity.open.api.aspect.UserInfo;
import com.ruyuan.commodity.open.api.client.shop.api.ShopCatOpenApi;
import com.ruyuan.commodity.open.api.model.base.CachePrefix;
import com.ruyuan.commodity.open.api.model.errorcode.GoodsErrorCode;
import com.ruyuan.commodity.open.api.model.promotion.tool.enums.PromotionTypeEnum;
import com.ruyuan.commodity.open.api.model.promotion.tool.vo.PromotionScriptVO;
import com.ruyuan.commodity.open.api.model.util.DateUtil;
import com.ruyuan.commodity.open.api.util.AuthContextUtil;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品sku业务类
 *
 * <li>sku表通过hashcode字段来确定是否有规格变化</li>
 * <li>通过lua脚本来更新库存</li>
 */
@Service
public class GoodsSkuManagerImpl implements GoodsSkuManager {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private GoodsInfoGalleryManager goodsInfoGalleryManager;

    @Autowired
    private GoodsQuantityManager goodsQuantityManager;

    @Autowired
    private RedisTemplate<String, String> cache;

    @Autowired
    private ShopCatOpenApi shopCatOpenApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private GoodsInfoQueryManager goodsInfoQueryManager;

    @Autowired
    private GoodsManager goodsManager;

    @Autowired
    private GoodsSkuMapper goodsSkuMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    /**
     * 发送消息的组件
     */
    @Autowired
    private MqMessageSenderFactory mqMessageSenderFactory;

    /**
     * 查询SKU列表
     *
     * @param goodsQueryParam
     * @return
     */
    @Override
    public WebPage list(GoodsQueryParam goodsQueryParam) {

        QueryWrapper<GoodsDO> wrapper = new QueryWrapper<>();
        //基础查询
        SearchUtil.baseQuery(goodsQueryParam, wrapper, "g.");
        //分类查询
        SearchUtil.categoryQuery(goodsQueryParam, wrapper, categoryMapper, "g.");
        // 店铺分组
        SearchUtil.shopCatQuery(goodsQueryParam, wrapper, shopCatOpenApi);

        wrapper.orderByDesc("g.goods_id");
        IPage<GoodsSelectorSkuVO> iPage = this.goodsMapper.querySkusPage(new Page<>(goodsQueryParam.getPageNo(), goodsQueryParam.getPageSize()), wrapper);

        return PageConvert.convert(iPage);
    }

    /**
     * 添加商品sku
     *
     * @param skuList sku集合
     * @param goods   商品do对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(List<GoodsSkuVO> skuList, GoodsDO goods) {

        List<GoodsSkuDO> newSkuList = new ArrayList<>();
        // 如果有规格
        if (skuList != null && skuList.size() > 0) {
            // 添加商品sku
            this.addGoodsSku(skuList, goods);

            //转为do
            skuList.forEach(skuVO -> {
                skuVO.setGoodsId(goods.getGoodsId());
                newSkuList.add(skuVO);
            });
        } else {
            // 添加没有规格的sku信息
            GoodsSkuDO newSku = this.addNoSku(goods);
            newSkuList.add(newSku);
        }

        //为新增的sku增加库存
        updateStock(newSkuList);
    }

    /**
     * 修改商品sku
     *
     * @param skuList sku集合
     * @param goods   商品do对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(List<GoodsSkuVO> skuList, GoodsDO goods) {
        // 新增的sku列表
        List<GoodsSkuDO> newSkuList = new ArrayList<>();
        Long goodsId = goods.getGoodsId();
        // 生成这个商品的所有sku的集合，不在这个集合的要删除
        String hashCodeStr = "";
        if (skuList != null) {
            for (GoodsSkuVO goodsSkuVO : skuList) {
                goodsSkuVO.setGoodsId(goodsId);
                // 计算hashcode
                int hashCode = buildHashCode(goodsSkuVO.getSpecList());
                goodsSkuVO.setHashCode(hashCode);
                if (!StringUtil.isEmpty(hashCodeStr)) {
                    hashCodeStr = hashCodeStr + ",";
                }
                hashCodeStr = hashCodeStr + "" + hashCode;
                // 新增的sku
                if (goodsSkuVO.getSkuId() == null || goodsSkuVO.getSkuId() == 0) {
                    GoodsSkuDO newSku = add(goodsSkuVO, goods);
                    newSku.setGoodsId(goodsId);
                    newSkuList.add(newSku);
                } else {
                    // 更新已经存在的
                    update(goodsSkuVO, goods);
                }
            }
        }
        // 清除不存在的sku的缓存及数据库,返回清除掉的skuId列表
        List<Long> delSkuIds = cleanNotExits(hashCodeStr, goodsId);
        // 没有规格的商品，用goods_id和hash_code=-1做为条件
        if (skuList == null || skuList.isEmpty()) {
            // 查找是否有不带规格的sku，如果有则更新，没有则添加一个
            QueryWrapper<GoodsSkuDO> queryWrapper = new QueryWrapper<GoodsSkuDO>()
                    .eq("goods_id", goods.getGoodsId())
                    .eq("hash_code", -1);
            int count = this.goodsSkuMapper.selectCount(queryWrapper);
            if (count > 0) {
                // 修改没有规格的sku信息
                GoodsSkuDO goodsSku = new GoodsSkuDO();
                BeanUtils.copyProperties(goods, goodsSku);
                // 没有规格的sku的hashcode 为-1
                goodsSku.setHashCode(-1);
                this.goodsSkuMapper.update(goodsSku, queryWrapper);
            } else {
                GoodsSkuDO newSku = addNoSku(goods);
                newSku.setGoodsId(goodsId);
                newSkuList.add(newSku);
            }
        }
        if (!CollectionUtils.isEmpty(newSkuList)) {
            // 为新增的sku增加库存
            updateStock(newSkuList);
        }
        // 重新计算商品的库存
        reCountGoodsStock(goodsId);
        // 发送商品sku变化消息
        mqMessageSenderFactory.createAndSendGoodsSkuUpdateMsg(delSkuIds, MsgTypeEnums.GOODS_SKU_CHANGE_MSG);
    }


    /**
     * 重新计算商品的库存
     *
     * @param goodsId
     */
    private void reCountGoodsStock(Long goodsId) {

        GoodsSkuDO goodsSku = this.goodsSkuMapper.selectOne(new QueryWrapper<GoodsSkuDO>()
                .select("sum(quantity) quantity", "sum(enable_quantity) enable_quantity")
                .eq("goods_id", goodsId));

        Integer quantity = goodsSku.getQuantity();
        Integer enableQuantity = goodsSku.getEnableQuantity();

        //更新数据库的库存
        this.goodsMapper.update(new GoodsDO(), new UpdateWrapper<GoodsDO>()
                .set("quantity", quantity)
                .set("enable_quantity", enableQuantity)
                .eq("goods_id", goodsId));

        //更新缓存的库存
        stringRedisTemplate.opsForValue().set(StockCacheKeyUtil.goodsActualKey(goodsId), "" + quantity);
        stringRedisTemplate.opsForValue().set(StockCacheKeyUtil.goodsEnableKey(goodsId), "" + enableQuantity);

    }

    /**
     * 更新商品的库存
     *
     * @param skuList
     */
    private void updateStock(List<GoodsSkuDO> skuList) {
        List<GoodsQuantityVO> quantityList = new ArrayList<>();
        skuList.forEach(sku -> {
            addStockToList(quantityList, sku);
        });
        goodsQuantityManager.updateSkuQuantity(quantityList);
    }

    /**
     * sku转为库存信息并压入list
     *
     * @param quantityList 要压入的库存list
     * @param sku          sku
     */
    private void addStockToList(List<GoodsQuantityVO> quantityList, GoodsSkuDO sku) {
        //实际库存vo
        GoodsQuantityVO actualQuantityVO = new GoodsQuantityVO();
        actualQuantityVO.setQuantity(sku.getQuantity() == null ? 0 : sku.getQuantity());
        actualQuantityVO.setGoodsId(sku.getGoodsId());
        actualQuantityVO.setSkuId(sku.getSkuId());
        actualQuantityVO.setQuantityType(QuantityType.actual);

        //可用库存vo
        GoodsQuantityVO enableQuantityVO = new GoodsQuantityVO();
        enableQuantityVO.setQuantity(sku.getQuantity() == null ? 0 : sku.getQuantity());
        enableQuantityVO.setGoodsId(sku.getGoodsId());
        enableQuantityVO.setSkuId(sku.getSkuId());
        enableQuantityVO.setQuantityType(QuantityType.enable);

        quantityList.add(actualQuantityVO);
        quantityList.add(enableQuantityVO);
    }

    /**
     * 清除不存在的sku的缓存及数据库
     *
     * @param hashCodeStr
     * @param goodsId
     * @return
     */
    private List<Long> cleanNotExits(String hashCodeStr, Long goodsId) {

        QueryWrapper<GoodsSkuDO> wrapper = new QueryWrapper<GoodsSkuDO>().select("sku_id").eq("goods_id", goodsId);

        if (StringUtil.isEmpty(hashCodeStr)) {
            wrapper.ne("hash_code", -1);
        } else {
            wrapper.notIn("hash_code", Arrays.asList(hashCodeStr.split(",")));
        }
        List<GoodsSkuDO> list = this.goodsSkuMapper.selectList(wrapper);
        List<Long> skuIdList = list.stream().map(GoodsSkuDO::getSkuId).collect(Collectors.toList());

        List<String> keys = StockCacheKeyUtil.skuKeys(skuIdList);

        logger.debug("删除keys: [{}]", keys.toString());

        if (keys != null && !keys.isEmpty()) {
            stringRedisTemplate.delete(keys);
        }

        // 批量删除：hashcode 不存在的 ，但不能是hashcode=-1的，因为有可能是没有规格导致的skuList为空
        this.goodsSkuMapper.delete(wrapper);
        return skuIdList;
    }

    /**
     * 查询某商品的sku
     *
     * @param goodsId 商品id
     * @return
     */
    @Override
    public List<GoodsSkuVO> listByGoodsId(Long goodsId) {

        List<GoodsSkuDO> list = goodsSkuMapper.selectList(new QueryWrapper<GoodsSkuDO>()
                .eq("goods_id", goodsId)
                .orderByAsc("price")
        );


        List<GoodsSkuVO> result = new ArrayList<>();
        for (GoodsSkuDO sku : list) {
            GoodsSkuVO skuVo = new GoodsSkuVO();
            BeanUtils.copyProperties(sku, skuVo);
            result.add(skuVo);
        }
        return result;
    }

    /**
     * 缓存中查询sku信息
     *
     * @param skuId skuid
     * @return
     */
    @Override
    public GoodsSkuVO getSkuFromCache(Long skuId) {
        // 从缓存读取sku信息
        GoodsSkuVO skuVo = JSONUtil.toBean(cache.opsForValue().get(CachePrefix.SKU.getPrefix() + skuId), GoodsSkuVO.class);
        // 缓存中没有找到商品，或者最后修改时间为空（表示数据异常），从数据库中查询
        if (skuVo == null || skuVo.getLastModify() == null) {
            GoodsSkuDO sku = this.getModel(skuId);
            if (sku == null) {
                return null;
            }
            skuVo = getSku(skuId);
            return skuVo;
        } else {
            //填充sku中的库存信息
            fillStock(skuVo);
        }
        return skuVo;
    }

    /**
     * 查询sku信息
     *
     * @param skuId skuid
     * @return
     */
    @Override
    public GoodsSkuVO getSku(Long skuId) {
        GoodsSkuDO sku = this.getModel(skuId);
        GoodsSkuVO skuVo = new GoodsSkuVO();
        BeanUtils.copyProperties(sku, skuVo);

        //以下信息由商品中获取
        GoodsDO goods = this.goodsInfoQueryManager.getModel(sku.getGoodsId());

        skuVo.setLastModify(goods.getLastModify());
        skuVo.setGoodsTransfeeCharge(goods.getGoodsTransfeeCharge());
        skuVo.setDisabled(goods.getDisabled());
        skuVo.setMarketEnable(goods.getMarketEnable());
        skuVo.setTemplateId(goods.getTemplateId());
        skuVo.setGoodsType(goods.getGoodsType());
        //如果sku绑定的运费模板不为空的话则将script重新赋值
        if (skuVo.getTemplateId() != 0) {
            String scriptListStr = cache.opsForValue().get(CachePrefix.SHIP_SCRIPT.getPrefix() + skuVo.getTemplateId());
            List<String> scripts = JSONUtil.toList(scriptListStr, String.class);
            if (scripts != null) {
                skuVo.setScripts(scripts);
            }
        }
        cache.opsForValue().set(CachePrefix.SKU.getPrefix() + skuId, JSONUtil.toJsonStr(skuVo));
        return skuVo;
    }

    /**
     * 查询单个sku
     *
     * @param id skuid
     * @return
     */
    @Override
    public GoodsSkuDO getModel(Long id) {
        return this.goodsSkuMapper.selectById(id);
    }

    /**
     * 删除商品关联的sku
     *
     * @param goodsIds 商品id数组
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long[] goodsIds) {
        // 删除这个商品的sku缓存(必须要在删除库中sku前先删缓存),首先查出商品对应的sku_id
        QueryWrapper<GoodsSkuDO> wrapper = new QueryWrapper<GoodsSkuDO>().in("goods_id", Arrays.asList(goodsIds)).select("sku_id");
        List<GoodsSkuDO> list = this.goodsSkuMapper.selectList(wrapper);

        for (GoodsSkuDO sku : list) {
            cache.delete(CachePrefix.SKU.getPrefix() + sku.getSkuId());
        }
        this.goodsSkuMapper.delete(wrapper);
    }

    /**
     * 增加sku集合
     *
     * @param skuList
     * @param goods
     */
    private void addGoodsSku(List<GoodsSkuVO> skuList, GoodsDO goods) {

        for (GoodsSkuVO skuVO : skuList) {
            add(skuVO, goods);

        }
    }

    /**
     * 增加sku表中的商品信息
     *
     * @param skuVO SKU
     * @param goods 商品
     */
    private GoodsSkuDO add(GoodsSkuVO skuVO, GoodsDO goods) {
        skuVO.setGoodsId(goods.getGoodsId());
        GoodsSkuDO sku = new GoodsSkuDO();
        BeanUtils.copyProperties(skuVO, sku);

        sku.setEnableQuantity(sku.getQuantity());
        sku.setGoodsName(goods.getGoodsName());
        sku.setCategoryId(goods.getCategoryId());
        // 得到规格值的json
        Map map = getSpecListJson(skuVO.getSpecList());
        sku.setSpecs((String) map.get("spec_json"));
        sku.setGoodsId(goods.getGoodsId());
        sku.setSellerId(goods.getSellerId());
        sku.setSellerName(goods.getSellerName());
        String thumbnail = (String) map.get("thumbnail");
        sku.setThumbnail(thumbnail == null ? goods.getThumbnail() : thumbnail);
        if (sku.getHashCode() == null || sku.getHashCode() == 0) {
            int hashCode = buildHashCode(skuVO.getSpecList());
            sku.setHashCode(hashCode);
            skuVO.setHashCode(hashCode);

        }
        this.goodsSkuMapper.insert(sku);
        Long skuId = sku.getSkuId();
        skuVO.setSkuId(skuId);
        sku.setSkuId(skuId);

        return sku;
    }

    /**
     * 更新sku表中的商品信息
     *
     * @param sku   SKU
     * @param goods 商品
     */
    private void update(GoodsSkuVO sku, GoodsDO goods) {
        Map<String, Object> map = getSpecListJson(sku.getSpecList());

        this.goodsSkuMapper.update(new GoodsSkuDO(), new UpdateWrapper<GoodsSkuDO>()
                .set("category_id", goods.getCategoryId())
                .set("goods_name", goods.getGoodsName())
                .set("sn", sku.getSn())
                .set("price", sku.getPrice())
                .set("cost", sku.getCost())
                .set("weight", sku.getWeight())
                .set("thumbnail", map.get("thumbnail") == null ? goods.getThumbnail() : map.get("thumbnail"))
                .set("specs", map.get("spec_json"))
                .eq("sku_id", sku.getSkuId()));

    }

    /**
     * sku中的spec字段的操作，返回json
     *
     * @param specList 规格值集合
     * @return 返回规格图片
     */
    private Map<String, Object> getSpecListJson(List<SpecValueVO> specList) {
        Map<String, Object> map = new HashMap<>();
        String thumbnail = null;
        for (SpecValueVO specvalue : specList) {
            if (specvalue.getSpecType() == null) {
                specvalue.setSpecType(0);
            }
            if (specvalue.getSpecType() == 1) {
                GoodsGalleryDO goodsGallery = goodsInfoGalleryManager.getGoodsGallery(specvalue.getSpecImage());
                specvalue.setBig(goodsGallery.getBig());
                specvalue.setSmall(goodsGallery.getSmall());
                specvalue.setThumbnail(goodsGallery.getThumbnail());
                thumbnail = goodsGallery.getThumbnail();
                specvalue.setTiny(goodsGallery.getTiny());
                // 规格只有第一个规格有图片，所以找到有图片的规格后就可跳出循环
                break;
            }
        }
        map.put("spec_json", JSONUtil.toJsonStr(specList));
        map.put("thumbnail", thumbnail);
        return map;
    }

    /**
     * 添加没有规格的sku信息
     *
     * @param goods 商品信息
     * @return
     */
    private GoodsSkuDO addNoSku(GoodsDO goods) {

        GoodsSkuDO goodsSku = new GoodsSkuDO();
        BeanUtils.copyProperties(goods, goodsSku);
        goodsSku.setEnableQuantity(goodsSku.getQuantity());
        goodsSku.setHashCode(-1);
        this.goodsSkuMapper.insert(goodsSku);
        return goodsSku;
    }

    /**
     * 获得规格值hashCode
     *
     * @param specValueVOList 规格值集合
     * @return
     */
    private int buildHashCode(List<SpecValueVO> specValueVOList) {
        HashCodeBuilder codeBuilder = new HashCodeBuilder(17, 37);
        specValueVOList.forEach(specValueVO -> {
            String specValue = specValueVO.getSpecValue();
            codeBuilder.append(specValue);

        });
        return codeBuilder.toHashCode();
    }

    /**
     * 为sku填充库存信息<br/>
     * 库存的信息存储在单独的缓存key中<br/>
     * 由缓存中读取出sku的可用库存和实际库存，并分别设置到sku库存信息中，以保证库存的实时正确性<br/>
     *
     * @param goodsSkuVO
     */
    private void fillStock(GoodsSkuVO goodsSkuVO) {
        //获取缓存中sku的实际库存
        String cacheActualStock = stringRedisTemplate.opsForValue().get(StockCacheKeyUtil.skuActualKey(goodsSkuVO.getSkuId()));
        //获取缓存中sku的可用库存
        String cacheEnableStock = stringRedisTemplate.opsForValue().get(StockCacheKeyUtil.skuEnableKey(goodsSkuVO.getSkuId()));

        //如果以上两项都不为空，也就是缓存中都存在，那么就将缓存中的库存信息set进sku对象中
        if (StringUtil.notEmpty(cacheActualStock) && StringUtil.notEmpty(cacheEnableStock)) {
            goodsSkuVO.setQuantity(StringUtil.toInt(cacheActualStock, goodsSkuVO.getQuantity()));
            goodsSkuVO.setEnableQuantity(StringUtil.toInt(cacheEnableStock, goodsSkuVO.getEnableQuantity()));
        }

    }

    /**
     * 根据商品sku主键id集合获取商品信息
     *
     * @param skuIds
     * @return
     */
    @Override
    public List<GoodsSkuVO> query(Long[] skuIds) {

        return this.goodsSkuMapper.queryGoodsSkuVOList(Arrays.asList(skuIds));
    }

    /**
     * 根据商品信息更新sku的图片等信息
     *
     * @param goods 商品do对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSkuByGoods(GoodsDO goods) {

        UpdateWrapper<GoodsSkuDO> updateWrapper = new UpdateWrapper<GoodsSkuDO>()
                .set("category_id", goods.getCategoryId())
                .set("goods_name", goods.getGoodsName())
                .set("thumbnail", goods.getThumbnail())
                .eq("goods_id", goods.getGoodsId());
        // 如果此商品有规格则不对价格进行修改 单独在sku维护，否则需要同步商品的价格
        if (goods.getHaveSpec() == null || !GoodsHaveSpecEnums.HAVE_SPEC_YES.getCode().equals(goods.getHaveSpec())) {
            updateWrapper.set("price", goods.getPrice()).set("weight", goods.getWeight());
        }

        this.goodsSkuMapper.update(new GoodsSkuDO(), updateWrapper);
    }

    /**
     * 更新商品的sku，可能是添加，可能是修改
     * 修改商品的规格，可能是有规格商品变成无规格商品，也可能是无规格商品变成有规格商品，还可能是修改规格
     *
     * @param skuList sku集合
     * @param goodsId 商品id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editSkus(List<GoodsSkuVO> skuList, Long goodsId) {
        // 获取商品信息
        GoodsDO goods = goodsInfoQueryManager.getModel(goodsId);
        // 清除与该商品关联的缓存
        this.goodsManager.cleanGoodsAssociated(goodsId, goods.getMarketEnable());
        // 修改商品sku信息
        this.edit(skuList, goods);

        UpdateWrapper<GoodsDO> updateWrapper = new UpdateWrapper<GoodsDO>()
                .set("last_modify", DateUtil.getDateline())
                .eq("goods_id", goodsId);
        // 把sku列表中第一个元素的价格、成本、重量设置到商品表中
        if (StringUtil.isNotEmpty(skuList)) {
            Double price = skuList.get(0).getPrice();
            Double cost = skuList.get(0).getCost();
            Double weight = skuList.get(0).getWeight();
            for (GoodsSkuVO goodsSkuVO : skuList) {
                if (goodsSkuVO.getPrice() < price) {
                    price = goodsSkuVO.getPrice();
                    cost = goodsSkuVO.getCost();
                    weight = goodsSkuVO.getWeight();
                }
            }
            // 修改规格时，变更商品最后修改时间
            updateWrapper.set("price", price)
                    .set("cost", cost)
                    .set("weight", weight)
                    .set("have_spec", GoodsHaveSpecEnums.HAVE_SPEC_YES.getCode());
            this.goodsMapper.update(new GoodsDO(), updateWrapper);
            // 发送更新商品的消息
            mqMessageSenderFactory.createAndSendMsg(new Long[]{goodsId}, MsgTypeEnums.GOODS_CHANGE_UPDATE_MSG,
                    false, false, "");
        } else {
            // 原来有规格，现在变成没有规格了
            if (goods.getHaveSpec() != null && GoodsHaveSpecEnums.HAVE_SPEC_YES.getCode().equals(goods.getHaveSpec())) {
                updateWrapper.set("have_spec", GoodsHaveSpecEnums.HAVE_SPEC_NO.getCode());
                this.goodsMapper.update(new GoodsDO(), updateWrapper);
            }
        }
    }

    @Override
    public Boolean checkExist(Long skuId) {
        QueryWrapper<GoodsSkuDO> condition = new QueryWrapper<>();
        condition.eq("sku_id", skuId).last("limit 1");
        Integer count = this.goodsSkuMapper.selectCount(condition);
        return count == 1;
    }

}
